package com.syezon.wifikey.ad;

import android.arch.lifecycle.MutableLiveData;
import android.arch.lifecycle.ViewModel;

import com.blankj.utilcode.util.AppUtils;
import com.hodanet.appadvplatclient.AdvClient;
import com.hodanet.appadvplatclient.ad.AdInfo;
import com.hodanet.appadvplatclient.api.BaseResult;
import com.hodanet.appadvplatclient.api.HttpClient;
import com.hodanet.appadvplatclient.utils.ClientInfoUtils;
import com.syezon.wifikey.ad.config.ConfigObserver;
import com.syezon.wifikey.channel.ChannelConfig;

import org.json.JSONObject;

import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.Observer;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;


public class SimuAdViewModel extends ViewModel implements ConfigObserver {

    private static final String DOMAIN = "https://www.e-tui.net";

    private static final String PATH_SIMU = "/simu/getUrlInfo.htm";
    private static final String PATH_SIMU_REPORT = "/simu/repoUrlOp.htm";


    protected MutableLiveData<SimuClickAdInfo> adLiveData = new MutableLiveData<>();

    private AdPositionEnum adPositionEnum = AdPositionEnum.SIMU_WEB;

    private static SimuClickAdInfo EMPTY = null;


    public SimuAdViewModel() {
        ConfigService.getInstance().registerObserver(this);
    }

    public MutableLiveData<SimuClickAdInfo> getAdLiveData() {
        return adLiveData;
    }

    @Override
    public void onChange(boolean showAd) {
        if (showAd && adPositionEnum != null) {
            getData(adPositionEnum);
        } else {
            adLiveData.postValue(EMPTY);
        }
    }

    @Override
    protected void onCleared() {
        super.onCleared();
        ConfigService.getInstance().unRegisterObserver(this);
    }

    protected void getData(final AdPositionEnum adPositionEnum) {
        Observable.create(new ObservableOnSubscribe<BaseResult<List<AdInfo>>>() {
            @Override
            public void subscribe(ObservableEmitter<BaseResult<List<AdInfo>>> observableEmitter) throws Exception {
                BaseResult<List<AdInfo>> advs = AdvClient.getInstance().getAdvs(adPositionEnum.getPosId(), ChannelConfig.getChannel(), AppUtils.getAppVersionCode());
                observableEmitter.onNext(advs);
            }
        }).map(new Function<BaseResult<List<AdInfo>>, SimuClickAdInfo>() {
            @Override
            public SimuClickAdInfo apply(BaseResult<List<AdInfo>> result) throws Exception {
                if (result != null && result.getData() != null && !result.getData().isEmpty()) {
                    try {
                        AdInfo adInfo = result.getData().get(0);
                        Map<String, String> param = new HashMap<>();
//                        param.put("imei", ClientInfoUtils.getImei());
//                        param.put("cid", ChannelConfig.getChannel());
                        String requestUrl = adInfo.getUrl();
                        if (adInfo.getUrl() != null && !adInfo.getUrl().endsWith("&")) {
                            requestUrl = requestUrl + "&imei=" + ClientInfoUtils.getImei();
                        }
                        String simuResult = HttpClient.getResult(requestUrl);
                        SimuClickAdInfo simuClickAdInfo = parseSimuAd(simuResult);
                        if (simuClickAdInfo != null) {
                            simuClickAdInfo.setAdInfo(adInfo);
                        }
                        return simuClickAdInfo;
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                return null;
            }
        }).subscribeOn(Schedulers.io())
                .subscribe(new Observer<SimuClickAdInfo>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                    }
                    @Override
                    public void onError(Throwable e) {
                        adLiveData.postValue(EMPTY);
                    }
                    @Override
                    public void onComplete() {
                    }
                    @Override
                    public void onNext(SimuClickAdInfo result) {
                        if (result != null) {
                            adLiveData.postValue(result);
                        } else {
                            adLiveData.postValue(EMPTY);
                        }
                    }
                });
    }

    public static void reportSimuAd(final long linkId, final int opType, final String cid) {
        Observable.create(new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(ObservableEmitter<String> observableEmitter) throws Exception {
                String simuResult = null;
                try {
                    Map<String, String> param = new HashMap<>();
                    param.put("urlId", linkId + "");
                    param.put("imei", ClientInfoUtils.getImei());
                    param.put("cid", cid + "");
                    param.put("opType", opType + "");
                    simuResult = HttpClient.postResult(getUrl(DOMAIN, PATH_SIMU_REPORT, param), "");
                } catch (IOException e) {
                    e.printStackTrace();
                }
                observableEmitter.onNext(simuResult);
            }
        })
                .subscribeOn(Schedulers.io())
                .subscribe(new Observer<String>() {
                    @Override
                    public void onError(Throwable e) {
                    }

                    @Override
                    public void onComplete() {

                    }

                    @Override
                    public void onSubscribe(Disposable disposable) {

                    }

                    @Override
                    public void onNext(String result) {

                    }
                });
    }

    private static String getUrl(String domain, String path, Map<String, String> param) {
        String url = "";
        StringBuilder sb = new StringBuilder();
        sb.append(url)
                .append(domain)
                .append(path);
        if (param != null && !param.isEmpty()) {
            if (!path.endsWith("?")) {
                sb.append("?");
            }
            Iterator<Map.Entry<String, String>> iterator = param.entrySet().iterator();
            int size = param.size();
            int index = 0;
            while (iterator.hasNext()) {
                Map.Entry<String, String> next = iterator.next();
                String key = next.getKey();
                String value = next.getValue();
                sb.append(key + "").append("=").append(value + "");
                index++;
                if (index < size) {
                    sb.append("&");
                }
            }
        }
        return sb.toString();
    }

    private SimuClickAdInfo parseSimuAd(String simuData) throws IOException {
        try {
            JSONObject jo = new JSONObject(simuData);
            int rc = jo.optInt("rc");
            if (rc == 1) {
                JSONObject joData = jo.optJSONObject("data");
                SimuClickAdInfo simuClickAdInfo = new SimuClickAdInfo();
                simuClickAdInfo.setUrlId(joData.optLong("urlId", 0L));
                simuClickAdInfo.setUrl(joData.optString("url", ""));
                simuClickAdInfo.setCid(joData.optString("cid", ""));
                int firstJump = joData.optInt("firstJump", 0);
                int secondJump = joData.optInt("secondJump", 0);
                double stayTime = joData.optDouble("stayTime", 1);
                if (firstJump == 1) {
//                    List<SimuClickAdInfo.SimuStep> steps = new ArrayList<>();
                    Map<Integer, SimuClickAdInfo.SimuStep> steps = new HashMap<>();
                    String firstCode = joData.optString("firstCode");
                    SimuClickAdInfo.SimuStep simuStepClickStep = new SimuClickAdInfo.SimuStep();
                    simuStepClickStep.setDelayTime((long) (stayTime * 1000));
                    simuStepClickStep.setOpJsCode(firstCode);
                    simuStepClickStep.setOpType(SimuClickAdInfo.SimuStep.OPTYPE_OPEN_PRE_FIRST_JUMP);
                    steps.put(1, simuStepClickStep);
                    double firstClickTime = joData.optDouble("firstClickTime", 2);
                    String firstClickCode = joData.optString("firstClickCode");
                    SimuClickAdInfo.SimuStep firstClickCodeStep = new SimuClickAdInfo.SimuStep();
                    firstClickCodeStep.setDelayTime((long) (firstClickTime * 1000));
                    firstClickCodeStep.setOpJsCode(firstClickCode);
                    firstClickCodeStep.setOpType(SimuClickAdInfo.SimuStep.OPTYPE_FIRST_JUMP);
                    steps.put(2, firstClickCodeStep);
                    int firstSlide = joData.optInt("firstSlide");
                    int stepOffset = 2;
                    if (firstSlide == 1) {
                        String firstSlideCode = joData.optString("firstSlideCode");
                        double firstSlideTime = joData.optDouble("firstSlideTime", 2);
                        SimuClickAdInfo.SimuStep firstSlideStep = new SimuClickAdInfo.SimuStep();
                        firstSlideStep.setDelayTime((long) (firstSlideTime * 1000));
                        firstSlideStep.setOpJsCode(firstSlideCode);
                        firstSlideStep.setOpType(SimuClickAdInfo.SimuStep.OPTYPE_FIRST_SLIDE);
                        steps.put(++stepOffset, firstSlideStep);
                    }
                    if (secondJump == 1) {
                        String secondClickCode = joData.optString("secondClickCode");
                        SimuClickAdInfo.SimuStep secondClickCodeStep = new SimuClickAdInfo.SimuStep();
                        secondClickCodeStep.setDelayTime(500);
                        secondClickCodeStep.setOpJsCode(secondClickCode);
                        secondClickCodeStep.setOpType(SimuClickAdInfo.SimuStep.OPTYPE_SENCODE_JUMP);
                        steps.put(++stepOffset, secondClickCodeStep);

                        int secondSlide = joData.optInt("secondSlide");
                        if (secondSlide == 1) {
                            String secondSlideCode = joData.optString("secondSlideCode");
                            double secondSlideTime = joData.optDouble("secondSlideTime");
                            SimuClickAdInfo.SimuStep secondSlideCodeStep = new SimuClickAdInfo.SimuStep();
                            secondSlideCodeStep.setDelayTime((long) (secondSlideTime * 1000));
                            secondSlideCodeStep.setOpJsCode(secondSlideCode);
                            secondSlideCodeStep.setOpType(SimuClickAdInfo.SimuStep.OPTYPE_SENCODE_SLIDE);
                            steps.put(++stepOffset, secondSlideCodeStep);
                        }

                    }
                    simuClickAdInfo.setSimuSteps(steps);
                }
                return simuClickAdInfo;
            }
        } catch (Throwable e) {
            throw new IOException("解析异常");
        }
        return null;
    }
}
